home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Apple Guide / Engineering / Context Check Modules / Standard CC Modules / Beep External / Beep.c next >
Encoding:
C/C++ Source or Header  |  1994-01-31  |  5.3 KB  |  202 lines  |  [TEXT/MPS ]

  1. //    Copyright:    © 1993 Apple Computer, Inc. All rights reserved.
  2. //    Author:        John R. Powers, III
  3. //    Date:            31-Jan-94
  4.  
  5. /*
  6.     This module is an example of an external module that can
  7.     be called by Reno with a kResContext or kResEvent.
  8.     See Reno ERS Part 4 - External Modules for more information.
  9.  
  10.     The structure being passed to the module is a simple array
  11.     of bytes (a string) with no length byte or terminator.
  12.     
  13.     A kResEvent that would invoke this module would
  14.     look like the following:
  15.  
  16.                 // Beep Apple Event (External Module Test)
  17.         
  18.         resource kResEvent (1001, Purgeable) {
  19.             front,        // target
  20.             'ApCx',        // class
  21.             'BEEP',        // Apple event id
  22.             none,            // not used, always none.
  23.             'ctxt',        // required key
  24.             "1,2"            // data - duration and count
  25.         };
  26.         
  27.     A kResContext that would invoke this module requires
  28.     that a "Beeper" case be added to the type
  29.     definition for kResContext in RenoDataTypes.r.  The
  30.     following is an example:
  31.     
  32.         switch {
  33.         …
  34.             case Beeper:
  35.                 key longint = 'BEEP';
  36.                 string;
  37.         …
  38.     
  39.     Then you can make as many kResContext's as you like
  40.     in the Reno content file.  They would look like the following:
  41.  
  42.                 // Beep "Context Check" (External Module Test)
  43.         
  44.         resource kResContext (1001, Purgeable) {
  45.             front,        // target
  46.             Beeper {
  47.                 "1,2"            // data -    duration and count
  48.             },
  49.         };
  50.     
  51.     In the kResContext example, the "1,2" string is NOT a
  52.     pascal string.  There should be no length byte.  The
  53.     resource contents should look something like this:
  54.     
  55.         f***BEEP1,2
  56.     
  57.     The target ('f***' for front application)
  58.     and module name ('BEEP') are required and are followed by the
  59.     data in string form.  There is no length byte.
  60.     A null terminator (IE C-string) is okay, but not required.
  61.         
  62.     History:
  63.         
  64.         1.0d1e1 30-Jun-92        new
  65.         1.0d1e2 13-Jul-92        change file type from 'ctxt' to 'extm'
  66.                                     change creator from 'ctxt' to 'reno'
  67.         1.0d2 24-Jul-92        parse string, remove header files.
  68.         1.0d3 23-Oct-92        tune-up for Reno 1.0a6.
  69.         1.0d4 18-Nov-92        make more data-fault-tolerant for Reno 1.0a7.
  70.         
  71.     31-Jan-94 1.2a5e1 <3.01>    Add "TextUtils.h" for build with ETO #13.
  72.  
  73.     There is NO Beep.h header file.
  74.     There is NO Proto.h header file.
  75.     There is NO Utility.h header file.
  76.     There is NO AllHeaders.h header file.
  77. */
  78.  
  79.         // Toolbox headers
  80.  
  81. #include    "Types.h"
  82. #include    "Memory.h"
  83. #include    "OSUtils.h"
  84. #include    "Packages.h"
  85. #include    "TextUtils.h"
  86.  
  87.         // Prototypes
  88. OSErr
  89. setOutMessage(void* theData, Size theSize, void* outMessage, Size* outSize);
  90.  
  91. void
  92. parseString (char* inStr, Size strLen, short pData[], short* dataCnt);
  93.  
  94.  
  95. // ------------------------------------------------------------------------
  96. // Entrypoint
  97. // We are passed a string containing the duration and count separated by commas.
  98. // The string has no length byte or terminator.  Length is in inSize.
  99. //
  100. // msg is the incoming array of bytes.
  101. // inSize is the size of msg in bytes.
  102. // outMessage is an outgoing array of bytes.
  103. // outSize is the size of outMessage in bytes.
  104. // startGlobals is a handler to this module's startup globals, if any.
  105. //
  106. pascal OSErr
  107. main(char* msg, Size inSize, void* outMessage, Size* outSize, Handle /*startGlobals*/)
  108. {
  109.     short        i;
  110.     long        result=0;
  111.     OSErr        err = noErr;
  112.     short        dataCnt=0;
  113.     short        dataVal[10];
  114.  
  115.     if(inSize>0)
  116.     {
  117.                 // We have incoming data,
  118.                 // parse string to get comma-separated values.
  119.         parseString(msg, inSize, dataVal, &dataCnt);
  120.                 // If we have any data, use it.
  121.         if (dataCnt>0)
  122.         {
  123.             short duration = dataVal[0];
  124.             short count = dataVal[1];
  125.             for(i=0; i<count; i++)
  126.             {
  127.                 SysBeep(duration);
  128.             }
  129.         }
  130.     }
  131.             // Return the result.
  132.     err = setOutMessage(&result, sizeof(Boolean), outMessage, outSize);
  133.     return(err);
  134. }
  135.  
  136. // ------------------------------------------------------------------------
  137. // parseString
  138. // Parse the string into a list of shorts.
  139. // Each item is separated by a comma.
  140. // Spaces and nulls ('\0') are ignored.
  141. // Two consecutive commas generate a zero value.
  142. // Caller MUST initialize dataCnt,
  143. // it is NOT initialized in this function, only incremented.
  144. // strLen is treated as a local variable initialized by the caller.
  145. void
  146. parseString (char* inStr, Size strLen, short dataVal[], short* dataCnt)
  147. {
  148.     char        ch;
  149.     short        itemLen=0;
  150.     Str255    itemStr;
  151.     long        itemVal;
  152.     
  153.     while(strLen>0)
  154.     {
  155.                 // Take character from string.
  156.         ch = *inStr++;
  157.         strLen--;
  158.                 // Is the character anything but a space, comma, or null?
  159.         if(ch!=' ' && ch!=',' && ch!='\0')
  160.         {
  161.                 // Add character to item string (skip over length byte).
  162.             itemStr[++itemLen] = ch;
  163.         }
  164.                 // Are we at the end of an item (comma) or the string?
  165.         if(ch==',' || strLen==0)
  166.         {
  167.                     // At the end of an item (a comma) or the string.
  168.                     // Convert string to value and add it to the array.
  169.                     // If string is empty, the value will be zero.
  170.             itemStr[0] = itemLen;
  171.             StringToNum(itemStr, &itemVal);
  172.             dataVal[(*dataCnt)++] = (short) itemVal;
  173.             itemLen = 0;
  174.         }
  175.     }
  176. }
  177.     
  178. // ------------------------------------------------------------------------
  179. // setOutMessage
  180. // Create the outMessage array and transfer theData to it.
  181. // Set the outSize.
  182. // The receiver of the outMessage array must dispose the pointer.
  183. // This is done by Reno's Apple event handler for external modules.
  184. OSErr
  185. setOutMessage(void* theData, Size theSize, Ptr* outMessage, Size* outSize)
  186. {
  187.     Ptr    p;
  188.     
  189.     if (p = NewPtr(theSize))
  190.     {
  191.         BlockMove(theData, p, theSize);
  192.         
  193.         *outSize        =    theSize;
  194.         *outMessage    =    p;
  195.         
  196.         return(noErr);
  197.     }
  198.     else
  199.         return(MemError());
  200. }
  201.  
  202.